package com.atom.app.mvvm.net

import android.annotation.SuppressLint
import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkInfo
import android.telephony.TelephonyManager
import java.io.IOException
import java.net.*
import java.util.*

object NetworkUtil {
    private const val url = "http://www.baidu.com"
    private const val NET_CNNT_BAIDU_OK = 1 // NetworkAvailable
    private const val NET_CNNT_BAIDU_TIMEOUT = 2 // no NetworkAvailable
    private const val NET_NOT_PREPARE = 3 // Net no ready
    private const val NET_ERROR = 4 //net error
    private const val TIMEOUT = 3000 // TIMEOUT


    /**
     * check NetworkAvailable
     * @param context
     * @return
     */
    @SuppressLint("MissingPermission")
    fun isNetworkAvailable(context: Context): Boolean {
        val manager = context.applicationContext.getSystemService(
            Context.CONNECTIVITY_SERVICE
        )?.let {
            it as ConnectivityManager
        } ?: return false
        val info = manager.activeNetworkInfo
        return !(null == info || !info.isAvailable)
    }

    /**
     * getLocalIpAddress
     * @return
     */
    fun getLocalIpAddress(): String {
        var ret = ""
        try {
            val en: Enumeration<NetworkInterface> = NetworkInterface.getNetworkInterfaces()
            while (en.hasMoreElements()) {
                val intf: NetworkInterface = en.nextElement()
                val enumIpAddr: Enumeration<InetAddress> = intf.inetAddresses
                while (enumIpAddr.hasMoreElements()) {
                    val inetAddress: InetAddress = enumIpAddr.nextElement()
                    if (!inetAddress.isLoopbackAddress) {
                        ret = inetAddress.hostAddress.toString()
                    }
                }
            }
        } catch (ex: SocketException) {
            ex.printStackTrace()
        }
        return ret
    }

    /**
     * 返回当前网络状态
     *
     * @param context
     * @return
     */
    @SuppressLint("MissingPermission")
    fun getNetState(context: Context): Int {
        try {
            val connectivity: ConnectivityManager = context
                .getSystemService(Context.CONNECTIVITY_SERVICE)?.let {
                    it as ConnectivityManager
                } ?: return NET_ERROR
            val networkinfo = connectivity.activeNetworkInfo
            if (networkinfo != null) {
                return if (networkinfo.isAvailable && networkinfo.isConnected) {
                    if (!connectionNetwork()) NET_CNNT_BAIDU_TIMEOUT else NET_CNNT_BAIDU_OK
                } else {
                    NET_NOT_PREPARE
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return NET_ERROR
    }

    /**
     * ping "http://www.baidu.com"
     * @return
     */
    private fun connectionNetwork(): Boolean {
        var result = false
        var httpUrl: HttpURLConnection? = null
        try {
            httpUrl = URL(url)
                .openConnection() as HttpURLConnection
            httpUrl.connectTimeout = TIMEOUT
            httpUrl.connect()
            result = true
        } catch (e: IOException) {
        } finally {
            httpUrl?.disconnect()
        }
        return result
    }

    /**
     * check is3G
     * @param context
     * @return boolean
     */
    fun is3G(context: Context): Boolean {
        val connectivityManager: ConnectivityManager = context
            .getSystemService(Context.CONNECTIVITY_SERVICE)?.let {
                it as ConnectivityManager
            } ?: return false
        val activeNetInfo = connectivityManager.activeNetworkInfo
        return (activeNetInfo != null
            && activeNetInfo.type == ConnectivityManager.TYPE_MOBILE)
    }

    /**
     * isWifi
     * @param context
     * @return boolean
     */
    fun isWifi(context: Context): Boolean {
        val connectivityManager: ConnectivityManager = context
            .getSystemService(Context.CONNECTIVITY_SERVICE)?.let {
                it as ConnectivityManager
            } ?: return false
        val activeNetInfo = connectivityManager.activeNetworkInfo
        return (activeNetInfo != null
            && activeNetInfo.type == ConnectivityManager.TYPE_WIFI)
    }

    /**
     * is2G
     * @param context
     * @return boolean
     */
    fun is2G(context: Context): Boolean {
        val connectivityManager = context
            .getSystemService(Context.CONNECTIVITY_SERVICE)?.let {
                it as ConnectivityManager
            } ?: return false
        val activeNetInfo = connectivityManager.activeNetworkInfo
        return (activeNetInfo != null
            && (activeNetInfo.subtype == TelephonyManager.NETWORK_TYPE_EDGE
            || activeNetInfo.subtype == TelephonyManager.NETWORK_TYPE_GPRS
            || activeNetInfo.subtype == TelephonyManager.NETWORK_TYPE_CDMA))
    }

    /**
     * is wifi on
     */
    @SuppressLint("MissingPermission")
    fun isWifiEnabled(context: Context): Boolean {
        val mgrConn: ConnectivityManager = context
            .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val mgrTel: TelephonyManager = context
            .getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        return mgrConn.activeNetworkInfo != null
            && (mgrConn.activeNetworkInfo!!.state == NetworkInfo.State.CONNECTED
            || mgrTel.networkType == TelephonyManager.NETWORK_TYPE_UMTS)
    }
}
